﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using System.Net.NetworkInformation;

public class Rocket : MonoBehaviour
{   
    // 
    public float moveSpeed;
    // 旋转速度
    public float roateSpeed;
    // 火箭飞行时间
    public float gameTime;
    // 火箭整体
    public Transform rocketBodyTrans;
    // 火箭单节对象、 火箭单节位置对象
    public GameObject[] rocketPartsGos;
    public Transform[] rocketPartsTrans;  
    // 火箭最后一节的索引
    private int currentIndex;
    // 脱落某一节后增加的速度倍速
    private int addSpeed;
    // 存储之前播放过的动画
    private Tween changeShortTween;
    // 
    public GameObject[] tipGos;
    // 摄像机控制
    private CameraController cameraController;
    // 火箭头  （最后一次火箭脱落 要看向火箭头）
    public Transform rocketHeadTrans;
    // 得分判定
    private int score;

    private bool gameStart = false;
    // 当拥有不同火箭节数 >=5 时 rocketBody的位置
    private float[] rocketLengthPosList;
    // 高发射塔
    public GameObject highTowerGo;
    // 低发射塔
    public GameObject lowTowerGo;

    // 火箭皮肤
    // 火箭连接点材质数组
    public Material[] attachMaterials;
    // 火箭身体材质数组
    public Material[] rocketBodyMaterials;
    // 火箭头游戏对象数组
    public GameObject[] rocketHeadGos;
    // 火箭连接点游戏对象数组
    public GameObject[] attachGos;
    // 火箭身体游戏对象数组
    public GameObject[] rocketBodyGos;
    // 连接点材质渲染组件数组
    private MeshRenderer[] attachMeshRenders;
    private MeshRenderer[] rocketBodyMeshRenders;
    private int testSkinIndex;

    // 特效
    // 爆炸特效
    public ParticleSystem explosionEffect;
    // 爆炸闪光特效
    public ParticleSystem ligthEffect;
    // 持续焰尾特效
    public ParticleSystem fireEffect;
    // 判定后的尾焰特效
    public ParticleSystem[] clickEffects;
    // 增加火箭长度特效
    public ParticleSystem addLengthEffects;
    // 发射前的火焰特效
    public ParticleSystem rocketStartFlyEffect;
    // 火箭发射前火箭身火星的特效
    public ParticleSystem rocketStartBodyEffect;
    // 持续尾焰效果动画
    public Tween fireTween;
    // 第11节（虚拟节）的位置
    public Transform bottomRocketPartTrans;
    // 判定后的尾焰特效动画
    private Tween clickTween;
    // 上一次判定后的尾焰特效索引
    private int lastClickEffectIndex;
    // 每节要播放火焰特效的位置有些差距  这个数组用来对没节展示得分火焰位置的微调
    private float[] clickValue;
    
    

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(PlayerManager.instance.rocketLength);
        cameraController = Camera.main.transform.GetComponent<CameraController>();
        // 游戏开始时将玩家还没有拥有的火箭节隐藏
        for(int i=0; i < PlayerManager.instance.rocketLength; i++)
        {
            rocketPartsGos[i].SetActive(false);
        }
        rocketLengthPosList = new float[6] {-3.82f,-3.14f,-2.58f,-1.78f,-0.93f,0};
        // 初始化连接点网格渲染组件数组
        attachMeshRenders = new MeshRenderer[attachGos.Length];
        for(int i=0; i< attachGos.Length; i++)
        {
            attachMeshRenders[i] = attachGos[i].GetComponent<MeshRenderer>();
        }
        rocketBodyMeshRenders = new MeshRenderer[rocketBodyGos.Length];
        for (int i=0;i< rocketBodyGos.Length; i++)
        {
            rocketBodyMeshRenders[i] = rocketBodyGos[i].GetComponent<MeshRenderer>();
        }
        // 初始化火箭身体网格渲染组件数组



        // 火箭节长度初始化  显示玩家拥有的火箭节
        InitRocketLength();
        // ChangeShort();
        ChangeRocketSkin(PlayerManager.instance.rocketID);
        testSkinIndex = PlayerManager.instance.rocketID;
        for(int i=0; i < tipGos.Length; i++)
        {
            tipGos[i].SetActive(false);
        }
        HideAllEffects();
        clickValue = new float[10] { 0, 0, 0.5f, 1, 1.7f, 1, 0.5f, 0.5f, 0.6f, 0.6f };

    }

    // Update is called once per frame
    void Update()
    {

        if (Input.GetKeyDown(KeyCode.A))
        {
            AddRocketLength();
        }
        if (Input.GetKeyDown(KeyCode.C))
        {
            testSkinIndex++;
            ChangeRocketSkin(testSkinIndex);
        }

/*        if (Input.GetKeyDown(KeyCode.D))
        {
            PlayerPrefs.DeleteAll();
        }*/

        if (!gameStart)
        {
            if (Input.GetMouseButtonDown(1))
            {
                StartGame();

            }
        }else{
            transform.Translate(moveSpeed * (addSpeed + 1) * ((int)gameTime / 3 + 1) * Time.deltaTime * Vector3.up, Space.World);
            gameTime += Time.deltaTime;
            rocketBodyTrans.Rotate(transform.up, roateSpeed * Time.deltaTime, Space.World);
            

            fireEffect.transform.position = rocketPartsGos[currentIndex].transform.position;
            fireEffect.Play();
        }





        if (Input.GetMouseButtonDown(0))
        {
            JudgeGetScore();
        }
        // 这个公式是当前火箭节没有全部脱落完  并且当前火箭节z轴高度已经缩短到0 了 
        // 说明游戏失败  火箭要爆炸
        if (currentIndex<= rocketPartsGos.Length -1 && rocketPartsTrans[currentIndex].localScale.z <= 0)
        {
            GameOver();
        }
    }

    private void InitRocketLength()
    {
        // 玩家拥有的火箭 节 显示
        currentIndex = 10 - PlayerManager.instance.rocketLength;
        rocketBodyTrans.localPosition= new Vector3(0, rocketLengthPosList[PlayerManager.instance.rocketLength-5],0);
        for(int i = currentIndex; i <= rocketPartsGos.Length - 1; i++)
        {
            rocketPartsGos[i].SetActive(true);
        }
        cameraController.ChangeCameraPos();
        if (PlayerManager.instance.rocketLength > 7)
        {
            highTowerGo.SetActive(true);
            lowTowerGo.SetActive(false);
        }
        else
        {
            highTowerGo.SetActive(false);
            lowTowerGo.SetActive(true);
        }
    }

    public void AddRocketLength()
    {
        PlayerManager.instance.rocketLength += 1;
        InitRocketLength();
        addLengthEffects.gameObject.SetActive(true);
        addLengthEffects.transform.position = rocketBodyTrans.transform.position;
        addLengthEffects.gameObject.transform.localScale = new Vector3(
            PlayerManager.instance.rocketLength-5,
            PlayerManager.instance.rocketLength-5,
            PlayerManager.instance.rocketLength-5
         );
        addLengthEffects.Play();
        PlayerPrefs.SetInt("RocketLength",PlayerManager.instance.rocketLength);
    }

    // 火箭脱落的方法
    private void LandPart(int scoreLevel)
    {
       
        if(currentIndex> rocketPartsGos.Length - 1)
        {
            return;
        }
        rocketPartsGos[currentIndex].transform.SetParent(null);
        if (changeShortTween != null)
        {
            changeShortTween.Kill();
        }
        if(currentIndex == rocketPartsGos.Length - 1)
        {
            // 最上面一节火箭脱落（从下往上脱落  也就式最后要脱落的一节脱落了）
            
            Debug.Log("游戏胜利!");
            UIManager.Instance.OpenGameWinPanel();
            // 最后一节脱落跟随火箭头
           // GetNewOffsetAndFollowTarget(rocketHeadTrans,true);
           MoveCamera(true);
        }
        else
        {
            //GetNewOffsetAndFollowTarget(rocketPartsGos[(rocketPartsGos.Length-1-currentIndex)/2+currentIndex+1].transform);
            MoveCamera(false);
            // 从下往上脱落 如果不是最上面一节火箭脱落
            currentIndex++;
            // 增加火箭移动速度 
            addSpeed++;
            // 让倒数第二节火箭部分开始变短
            ChangeShort(scoreLevel);
        }
    }

    // 火箭某一节逐渐变短
    private void ChangeShort(int scoreLevel)
    {
        //currentIndex 大于rocketPartsTrans数组长度说明前面已经全部脱落完了
        if (currentIndex > rocketPartsTrans.Length - 1)
        {
            return;
        }

        // 如果是最后一节脱落
        if(currentIndex == rocketPartsTrans.Length - 1)
        {
            // 当前节Z轴缩小  
            changeShortTween=  rocketPartsTrans[currentIndex].DOScaleZ(0,10);
            // 火箭脱落尾焰特效移动
            // EffectMove(Vector3 startPos,Vector3 endPos,float moveTime)
         /*   EffectMove(rocketPartsGos[currentIndex - 1].transform.localPosition,
                rocketPartsGos[currentIndex].transform.position, 2);*/
            // 前面已经脱落的那节 提示绿色部分隐藏
            tipGos[currentIndex-1].SetActive(false);
            // 当前节绿色提示部分 显示
            tipGos[currentIndex].SetActive(true);
        }
        else
        {
            // 如果不是最后一节脱落

            // 当前节Z轴缩小 
            changeShortTween =  rocketPartsTrans[currentIndex].DOScaleZ(0, 10);
            // 火箭脱落尾焰特效移动
            // EffectMove(Vector3 startPos,Vector3 endPos,float moveTime)
        /*    EffectMove(rocketPartsGos[currentIndex-1].transform.localPosition,
                rocketHeadTrans.transform.position,3);*/

            // 如果不是第一节 前面一节的提示信息要隐藏  并且显示当前节提示部分
            // 如果是第一节 没有前面一节  所以自己这节的提示部分显示就行了额
            if (currentIndex != 0)
            {
                tipGos[currentIndex -1].SetActive(false);
            }
            tipGos[currentIndex].SetActive(true);
        }
        MoveEffect(scoreLevel);

    }

    public void StartGame()
    {
        gameStart = true;
        fireEffect.gameObject.SetActive(true);
        ChangeShort(0);
    }

    public void PlayFlyEffect()
    {
        rocketStartFlyEffect.transform.position = rocketPartsGos[currentIndex].transform.position;
        rocketStartFlyEffect.gameObject.SetActive(true);
        rocketStartFlyEffect.Play();

        rocketStartBodyEffect.transform.position = rocketPartsGos[currentIndex].transform.position;
        rocketStartBodyEffect.gameObject.SetActive(true);
        rocketStartBodyEffect.Play();
    }

    /**
     * 火箭持续尾焰移动的方法
     */
    private void MoveEffect(int scoreLevel)
    {
        if (currentIndex+1>rocketPartsGos.Length-1)
        {
            return;
        }
        if (currentIndex == 0)
        {
            EffectMove(bottomRocketPartTrans.transform.position,
                rocketPartsGos[currentIndex + 1].transform.position, 1, scoreLevel);
        }
        else
        {
            EffectMove(rocketPartsGos[currentIndex].transform.position,
                rocketPartsGos[currentIndex + 1].transform.position, 1, scoreLevel);
        }
    }

    /*    public void GetNewOffsetAndFollowTarget(Transform newTargetTrans, bool stopFollow = false)
        {
            cameraController.GetNewOffsetAndFollowTarget(newTargetTrans, stopFollow);
        }*/

    public void MoveCamera(bool stopFollow = false)
    {
        cameraController.MoveCamera(stopFollow);
    }

    // 判定当次火箭的得分
    private void JudgeGetScore()
    {
        int scoreLevel = 0;
        if (rocketPartsTrans[currentIndex].localScale.z < 0.05f)
        {
            // 游戏结束
            GameOver();
        }
        else if (rocketPartsTrans[currentIndex].localScale.z<0.1f){
            // Excellent
            score += (currentIndex + 1) * 20;
            Debug.Log("Excellent");
            scoreLevel = 3;
        }
        else if (rocketPartsTrans[currentIndex].localScale.z < 0.25f)
        {
            // perfect
            score += (currentIndex + 1) * 10;
            Debug.Log("perfect");
            scoreLevel = 2;
        }
        else if (rocketPartsTrans[currentIndex].localScale.z < 0.5f)
        {
            // goood
            score += (currentIndex + 1) * 6;
            Debug.Log("goood");
            scoreLevel = 1;
        }
        else
        {
            // ok
            score += (currentIndex + 1) * 2;
            Debug.Log("ok");
            scoreLevel = 0;
        }
        LandPart(scoreLevel);
    }

    // 游戏失败
    private void GameOver()
    {
        gameStart = false;
        // 火箭脱落失败的那一节展示 爆炸特效
        explosionEffect.transform.position=rocketPartsTrans[currentIndex].position;
        explosionEffect.gameObject.SetActive(true);
        explosionEffect.Play();
        // 火箭脱落失败的那一节展示 闪光特效
        ligthEffect.transform.position = rocketPartsTrans[currentIndex].position;
        ligthEffect.gameObject.SetActive(true);
        ligthEffect.Play();
        // 摄像机抖动
        cameraController.transform.DOShakePosition(0.5f,10,20,180,true);
        Debug.Log("游戏结束");
        UIManager.Instance.OpenGameLosePanel();
    }

    // 更换火箭皮肤
    public void ChangeRocketSkin(int rocketIndex)
    {
        for(int i = 0; i < attachMeshRenders.Length; i++)
        {
            attachMeshRenders[i].material = attachMaterials[rocketIndex];
        }
        for (int i = 0; i < rocketBodyMeshRenders.Length; i++)
        {
            rocketBodyMeshRenders[i].material = rocketBodyMaterials[rocketIndex];
        }
        for(int i = 0; i < rocketHeadGos.Length; i++){
            rocketHeadGos[i].SetActive(false);
        }
        rocketHeadGos[rocketIndex].SetActive(true);
        PlayerManager.instance.rocketID = rocketIndex;
        PlayerPrefs.SetInt("RocketID", PlayerManager.instance.rocketID);
    }

    // 隐藏所有特效
    public void HideAllEffects()
    {
        explosionEffect.gameObject.SetActive(false);
        ligthEffect.gameObject.SetActive(false);
        fireEffect.gameObject.SetActive(false);
        for (int i = 0; i < clickEffects.Length; i++)
        {
            clickEffects[i].gameObject.SetActive(false);
        }
        addLengthEffects.gameObject.SetActive(false);
        rocketStartFlyEffect.gameObject.SetActive(false);
        rocketStartFlyEffect.gameObject.SetActive(false);
    }

    private int a = 0;
    // 火箭尾焰移动方法
    public void EffectMove(Vector3 startPos,Vector3 endPos,float moveTime,int scoreLevel)
    {
        a++;
        if (a ==1)
        {
            Debug.Log("---start---");
            Debug.Log(fireTween);
        }
        fireTween.Pause();
        Debug.Log(111111111111);
        fireEffect.Stop();
        fireEffect.Pause();
        fireEffect.transform.position = startPos;
        fireTween = fireEffect.transform.DOLocalMove(endPos, moveTime);
        fireTween.Play();

        clickEffects[lastClickEffectIndex].gameObject.SetActive(false);
        
        // 得分尾焰效果 根据得分不同 不同效果的显示位置 有微调
        clickEffects[scoreLevel].transform.position = 
            startPos-new Vector3(0, clickValue[currentIndex],0);
        clickEffects[scoreLevel].gameObject.SetActive(true);
        clickEffects[scoreLevel].Play();
        clickTween.Pause();
        clickTween = clickEffects[scoreLevel].transform.DOLocalMove(endPos, moveTime);
        clickTween.Play();
        lastClickEffectIndex= scoreLevel;
    }

   public void Replay()
    {
        PlayerManager.instance.money += score / 10;
        PlayerPrefs.SetInt("Money",PlayerManager.instance.money);
        if (score > PlayerManager.instance.playerBestScore) {
            PlayerPrefs.SetInt("PlayerBestScore", score);
        }
        UIManager.Instance.ShowMask();

    }
    
}
